package core.score;

import core.games.Game;
import domain.BowlingFrame;
import domain.Frame;

import java.util.List;

import static config.Constants.NORMAL_FRAMES;

public abstract class BowlingScoreStrategy implements ScoreStrategy {
    @Override
    public int calculateScore(Game game) {
        List<Frame> frames = game.getFrames();
        boolean done = frames.size() >= NORMAL_FRAMES;
        for (Frame frame : frames) {
            if (!frame.isValid()) done = false;
        }
        if (done) {
            int totalScore = 0;
            for (int i = 0; i < frames.size() - 1; i++) {
                totalScore += calculateFrameScore((BowlingFrame) frames.get(i), (BowlingFrame) frames.get(i + 1));
            }
            totalScore += calculateFrameScore((BowlingFrame) frames.get(frames.size() - 1), null);
            return totalScore;
        }
        return 0;
    }


    private int calculateFrameScore(BowlingFrame curFrame, BowlingFrame nextFrame) {
        if (curFrame == null) return 0;
        return switch (curFrame.getType()) {
            case NORMAL -> curFrame.getFirstScore() + curFrame.getSecondScore();
            case STRIKE -> curFrame.getFirstScore() +
                    (nextFrame != null ? nextFrame.getFirstScore() + nextFrame.getSecondScore() : 0);
            case SPARE -> curFrame.getFirstScore() + curFrame.getSecondScore() +
                    (nextFrame != null ? nextFrame.getFirstScore() : 0);
        };
    }
}
